package com.web.estate.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * 
 * @author:liujie.liuj
 * @date:2011-3-31
 * 
 */
public class RestUrlRewriteFilter extends OncePerRequestFilter implements Filter {
	private static final String DEFAULT_EXECUDE_EXTENTIONS = "jsp,jspx,do";
	private static final String DEFAULT_PREFIX = "/static";

	private String prefix;
	private boolean debug = false;
	private String[] excludeExtentions = new String[0];
	private String[] excludePrefixes = new String[0];

	private static Log log = LogFactory.getLog(RestUrlRewriteFilter.class);

	protected void initFilterBean() throws ServletException {
		try {
			initParameter(getFilterConfig());
		} catch (IOException e) {
			throw new ServletException("init paramerter error", e);
		}
	}

	private void initParameter(FilterConfig filterConfig) throws IOException {
		prefix = getStringParameter(filterConfig, "prefix", DEFAULT_PREFIX);
		debug = getBooleanParameter(filterConfig, "debug", false);
		String excludeExtentionsString = getStringParameter(filterConfig, "excludeExtentions",
				DEFAULT_EXECUDE_EXTENTIONS);
		excludeExtentions = excludeExtentionsString.split(",|( +)");

		String excludePrefixsString = getStringParameter(filterConfig, "excludePrefixes", null);
		if (StringUtils.hasText(excludePrefixsString)) {
			excludePrefixes = excludePrefixsString.split(",");
		}
		log.info("Prifix of URL rewrite rule : " + prefix);
		log.info("ExcludeExtentions of URL rewrite rule : " + excludeExtentionsString);
		log.info("ExcludePrefixes of URL rewrite rule : " + excludePrefixsString);

	}

	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		String from = request.getRequestURI().substring(request.getContextPath().length());
		if (rewriteURL(from)) {
			final String to = prefix + from;
			if (debug) {
				log.debug("forward request from " + from + " to " + to);
			}
			request.getRequestDispatcher(to).forward(request, response);
		} else {
			if (debug) {
				log.debug("not rewrite url:" + request.getRequestURI());
			}
			filterChain.doFilter(request, response);
		}
	}

	private boolean rewriteURL(String from) {
		if (from == null) {
			return false;
		}

		int sepIndex = from.lastIndexOf(".");
		String extension = (sepIndex != -1 ? from.substring(sepIndex + 1) : null);

		if (null == extension || "".equals(extension.trim())) {
			return false;
		}

		for (String excludePrefix : excludePrefixes) {
			if (from.startsWith(excludePrefix)) {
				return false;
			}
		}

		for (String excludeExtension : excludeExtentions) {
			if (excludeExtension.equals(extension)) {
				return false;
			}
		}
		return true;
	}

	private String getStringParameter(FilterConfig filterConfig, String name, String defaultValue) {
		String value = filterConfig.getInitParameter(name);
		if (value == null || value.trim().length() == 0) {
			return defaultValue;
		}
		return value;
	}

	private boolean getBooleanParameter(FilterConfig filterConfig, String name, boolean defaultValue) {
		String value = getStringParameter(filterConfig, name, String.valueOf(defaultValue));
		return Boolean.parseBoolean(value);
	}
}